home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 09 - 1993 / 09.06 Jun 93 / C Shell XCMD / BEditDoc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-01  |  9.0 KB  |  380 lines  |  [TEXT/KAHL]

  1. /******************************************************************************
  2.     BEditDoc.c
  3.     
  4.     Document methods for a tiny editor.
  5.         
  6.     Copyright © 1989 Symantec Corporation. All rights reserved.
  7.  
  8.  ******************************************************************************/
  9.  
  10. #include <Global.h>
  11. #include <Commands.h>
  12. #include <CApplication.h>
  13. #include <CBartender.h>
  14. #include <CDataFile.h>
  15. #include <CDecorator.h>
  16. #include <CDesktop.h>
  17. #include <CError.h>
  18. #include <CPanorama.h>
  19. #include <CScrollPane.h>
  20. #include <TBUtilities.h>
  21. #include "BEditDoc.h"
  22. #include "BEditPane.h"
  23. #include "CWindow.h"
  24.  
  25. #define    WINDculture        500        /* Resource ID for WIND template */
  26.  
  27. extern    CApplication *gApplication;    /* The application */
  28. extern    CBartender    *gBartender;    /* The menu handling object */
  29. extern    CDecorator    *gDecorator;    /* Window dressing object    */
  30. extern    CDesktop    *gDesktop;        /* The enclosure for all windows */
  31. extern    CBureaucrat    *gGopher;        /* The current boss in the chain of command */
  32. extern    OSType        gSignature;        /* The application's signature */
  33. extern    CError        *gError;        /* The error handling object */
  34.  
  35. /***
  36.  * IEditDoc
  37.  *
  38.  *    This is your document's initialization method.
  39.  *    If your document has its own instance variables, initialize
  40.  *    them here.
  41.  *    The least you need to do is invoke the default method.
  42.  *
  43.  ***/
  44.  
  45. void BEditDoc::IEditDoc(CApplication *aSupervisor, Boolean printable)
  46.  
  47. {
  48.     CDocument::IDocument(aSupervisor, printable);
  49. }
  50.  
  51.  
  52. /***
  53.  * NewFile
  54.  *
  55.  *    When the user chooses New from the File menu, the CreateDocument()
  56.  *    method in your Application class will send a newly created document
  57.  *    this message. This method needs to create a new window, ready to
  58.  *    work on a new document.
  59.  *
  60.  *    Since this method and the OpenFile() method share the code for creating
  61.  *    the window, you should use an auxiliary window-building method.
  62.  *
  63.  ***/
  64. void BEditDoc::NewFile(void)
  65.  
  66. {
  67.         /**
  68.          **    BuildWindow() is the method that
  69.          **    does the work of creating a window.
  70.          **    It's parameter should be the data that
  71.          **    you want to display in the window.
  72.          **    Since this is a new window, there's nothing
  73.          **    to display.
  74.          **
  75.          **/
  76.  
  77.     BuildWindow(NULL);
  78.  
  79.         /**
  80.          **    Send the window a Select() message to make
  81.          **    it the active window.
  82.          **/
  83.     
  84.     itsWindow->Select();
  85. }
  86.  
  87.  
  88. /***
  89.  * OpenFile
  90.  *
  91.  *    When the user chooses Open… from the File menu, the OpenDocument()
  92.  *    method in your Application class will let the user choose a file
  93.  *    and then send a newly created document this message. The information
  94.  *    about the file is in the SFReply record.
  95.  *
  96.  *    In this method, you need to open the file and display its contents
  97.  *    in a window. This method uses the auxiliary window-building method.
  98.  *
  99.  ***/
  100.  
  101. void BEditDoc::OpenFile(SFReply *macSFReply)
  102.  
  103. {
  104.     CDataFile    *theFile;
  105.     Handle        theData;
  106.     Str63        theName;
  107.     OSErr        theError;
  108.  
  109.         /**
  110.          ** Create a file and send it a SFSpecify()
  111.          **    message to set up the name, volume, and
  112.          **    directory.
  113.          **
  114.          **/
  115.  
  116.     theFile = new(CDataFile);
  117.  
  118.         /**
  119.          **    Be sure to set the instance variable
  120.          **    so other methods can use the file if they
  121.          **    need to. This is especially important if
  122.          **    you leave the file open in this method.
  123.          **    If you close the file after reading it, you
  124.          **    should be sure to set itsFile to NULL.
  125.          **
  126.          **/
  127.  
  128.     itsFile = theFile;
  129.  
  130.     theFile->IDataFile();
  131.     theFile->SFSpecify(macSFReply);
  132.     
  133.  
  134.         /**
  135.          **    Send the file an Open() message to
  136.          **    open it. You can use the ReadSome() or
  137.          **    ReadAll() methods to get the contents of the file.
  138.          **
  139.          **/
  140.  
  141.     theFile->Open(fsRdWrPerm);
  142.     
  143.     if (theFile->GetLength() > 10240L)
  144.     {
  145.         ParamText( "\pCan't open a file this big.", "\p", "\p", "\p");
  146.         PositionDialog('ALRT', 128);
  147.         InitCursor();
  148.         Alert(128, NULL);
  149.         
  150.         Dispose();
  151.         return;
  152.     }
  153.     
  154.  
  155.     theData = theFile->ReadAll();     /* ReadAll() creates the handle */
  156.  
  157.     BuildWindow(theData);
  158.  
  159.         /**
  160.          **    In your application, you'll probably store
  161.          **    the data in some form as an instance variable
  162.          **    in your document class. For this example, there's
  163.          **    no need to save it, so we'll get rid of it.
  164.          **
  165.          **/
  166.  
  167.     DisposHandle(theData);
  168.  
  169.         /**
  170.          **    In this implementation, we leave the file
  171.          **    open. You might want to close it after
  172.          **    you've read in all the data.
  173.          **
  174.          **/
  175.  
  176.     itsFile->GetName(theName);
  177.     itsWindow->SetTitle(theName);
  178.     itsWindow->Select();            /* Don't forget to make the window active */
  179. }
  180.  
  181.  
  182.  
  183. /***
  184.  * BuildWindow
  185.  *
  186.  *    This is the auxiliary window-building method that the
  187.  *    NewFile() and OpenFile() methods use to create a window.
  188.  *
  189.  *    In this implementation, the argument is the data to display.
  190.  *
  191.  ***/
  192.  
  193. void BEditDoc::BuildWindow (Handle theData)
  194.  
  195. {
  196.     CScrollPane        *theScrollPane;
  197.     BEditPane        *theMainPane;
  198.     Rect            margin;
  199.  
  200.         /**
  201.          **    First create the window and initialize
  202.          **    it. The first argument is the resource ID
  203.          **    of the window. The second argument specifies
  204.          **    whether the window is a floating window.
  205.          **    The third argument is the window's enclosure; it
  206.          **    should always be gDesktop. The last argument is
  207.          **    the window's supervisor in the Chain of Command;
  208.          **    it should always be the Document object.
  209.          **
  210.          **/
  211.  
  212.     itsWindow = new(CWindow);
  213.     itsWindow->IWindow(WINDculture, FALSE, gDesktop, this);
  214.     
  215.         /**
  216.          **    After you create the window, you can use the
  217.          **    SetSizeRect() message to set the window’s maximum
  218.          **    and minimum size. Be sure to set the max & min
  219.          **    BEFORE you send a PlaceNewWindow() message to the
  220.          **    decorator.
  221.          **
  222.          ** The default minimum is 100 by 100 pixels. The
  223.          **    default maximum is the bounds of GrayRgn() (The
  224.          **    entire display area on all screens.)
  225.          **
  226.          **/
  227.  
  228.     theScrollPane = new(CScrollPane);
  229.     
  230.         /**
  231.          **    You can initialize a scroll pane two ways:
  232.          **        1. You can specify all the values
  233.          **           right in your code, like this.
  234.          **        2. You can create a ScPn resource and
  235.          **           initialize the pane from the information
  236.          **           in the resource.
  237.          **
  238.          **/
  239.  
  240.     theScrollPane->IScrollPane(itsWindow, this, 10, 10, 0, 0,
  241.                                 sizELASTIC, sizELASTIC,
  242.                                 TRUE, TRUE, TRUE);
  243.  
  244.         /**
  245.          **    The FitToEnclFrame() method makes the
  246.          **    scroll pane be as large as its enclosure.
  247.          **    In this case, the enclosure is the window,
  248.          **    so the scroll pane will take up the entire
  249.          **    window.
  250.          **
  251.          **/
  252.  
  253.     theScrollPane->FitToEnclFrame(TRUE, TRUE);
  254.  
  255.  
  256.         /**
  257.          **    itsMainPane is the document's focus
  258.          **    of attention. Some of the standard
  259.          **    classes (particularly CPrinter) rely
  260.          **    on itsMainPane pointing to the main
  261.          **    pane of your window.
  262.          **
  263.          **    itsGopher specifies which object
  264.          **    should become the gopher. By default
  265.          **    the document becomes the gopher. It’s
  266.          **    likely that your main pane handles commands
  267.          **    so you’ll almost want to set itsGopher
  268.          **    to point to the same object as itsMainPane.
  269.          **
  270.          **    Note that the main pane is the
  271.          **    panorama in the scroll pane and not
  272.          **    the scroll pane itself.
  273.          **
  274.          **/
  275.  
  276.     theMainPane = new(BEditPane);
  277.     itsMainPane = theMainPane;
  278.     itsGopher = theMainPane;
  279.  
  280.         /**
  281.          **    The IEditPane method automatically
  282.          **    fits the pane to the enclosure and
  283.          **    gives us a little margin.
  284.          **
  285.          **/
  286.  
  287.     theMainPane->IEditPane(theScrollPane, this);
  288.  
  289.         /**
  290.          **    Send the scroll pane an InstallPanorama()
  291.          **    to associate our pane with the scroll pane.
  292.          **
  293.          **/
  294.  
  295.     theScrollPane->InstallPanorama(theMainPane);
  296.  
  297.     if (theData)
  298.         theMainPane->SetTextHandle(theData);
  299.     
  300.         /**
  301.          **    The Decorator is a global object that takes care
  302.          **    of placing and sizing windows on the screen.
  303.          **    You don't have to use it.
  304.          **
  305.          **/
  306.  
  307.     gDecorator->PlaceNewWindow(itsWindow);
  308. }
  309.  
  310.  
  311.  
  312. /***
  313.  * DoSave
  314.  *
  315.  *    This method handles what happens when the user chooses Save from the
  316.  *    File menu. This method should return TRUE if the file save was successful.
  317.  *    If there is no file associated with the document, you should send a
  318.  *    DoSaveFileAs() message.
  319.  *
  320.  ***/
  321.  
  322. Boolean BEditDoc::DoSave(void)
  323.  
  324. {
  325.     Handle        theData;
  326.  
  327.     if (itsFile == NULL)
  328.         return(DoSaveFileAs());
  329.     else {
  330.         theData = (**((CEditText *)itsMainPane)->macTE).hText;
  331.         ((CDataFile *)itsFile)->WriteAll(theData);            
  332.         dirty = FALSE;                    /* Document is no longer dirty        */
  333.         gBartender->DisableCmd(cmdSave);
  334.         return(TRUE);                    /* Save was successful                */
  335.     }
  336. }
  337.  
  338.  
  339. /***
  340.  * DoSaveAs
  341.  *
  342.  *    This method handles what happens when the user chooses Save As… from
  343.  *    File menu. The default DoCommand() method for documents sends a DoSaveFileAs()
  344.  *    message which displays a standard put file dialog and sends this message.
  345.  *    The SFReply record contains all the information about the file you're about
  346.  *    to create.
  347.  *
  348.  ***/
  349.  
  350. Boolean BEditDoc::DoSaveAs(SFReply *macSFReply)
  351.  
  352. {
  353.         /**
  354.          **    If there's a file associated with this document
  355.          **    already, close it. The Dispose() method for files
  356.          **    sends a Close() message to the file before releasing
  357.          **    its memory.
  358.          **
  359.          **/
  360.          
  361.     if (itsFile != NULL)
  362.         itsFile->Dispose();
  363.  
  364.  
  365.         /**
  366.          **    Create a new file, and then save it normally.
  367.          **
  368.          **/
  369.  
  370.     itsFile = new(CDataFile);
  371.     ((CDataFile *)itsFile)->IDataFile();
  372.     itsFile->SFSpecify(macSFReply);
  373.     itsFile->CreateNew(gSignature, 'TEXT');
  374.     itsFile->Open(fsRdWrPerm);
  375.     
  376.     itsWindow->SetTitle(macSFReply->fName);
  377.  
  378.     return( DoSave() );
  379. }
  380.